﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace StringSearch
{
    class TinyMatcher : Matcher
    {
        private int MAX_SYMBOLS = 256;
        private uint _f;
        private uint _t;
        private uint[] _sigma;
//         private Dictionary<int, int> _founds; 
//         public Dictionary<int, int> Founds
//         {
//             get
//             {
//                 return this._founds;
//             }
//         }

        public TinyMatcher()
        {
            this._patterns = null;
            this._f = 0;
            this._t = 0;
            this._sigma = null;
        }

        public TinyMatcher(string[] _patterns)
        {
            this._patterns = _patterns;
            this._f = 0;
            this._t = 0;
            this._sigma = new uint[MAX_SYMBOLS];
            for (int i = 0; i < MAX_SYMBOLS; i++) this._sigma[i] = 0;
            uint r = 1;
            uint _r = 0;
            for (int i = 0; i < this._patterns.Length; i++)
            {
                this._f |= r;
                for (int j = 0; j < this._patterns[i].Length; j++)
                {
                    this._sigma[Convert.ToInt16(this._patterns[i][j])] |= r;
                    _r = r;
                    r <<= 1;
                }
                this._t |= _r;
            }
        }

        public override void Search(String str)
        {
            int j = 0;
			int[] check = new int[this._patterns.Length];
            for (int i = 0; i < this._patterns.Length; i++)
            {
                j += this._patterns[i].Length;
				check[i] = 1 << (j - 1);
            }
            if (this._founds == null) this._founds = new Dictionary<int, List<int>>();
            
            uint r = this._f;
            for (int i = 0; i < str.Length; i++)
            {
                r = ((r << 1) | this._f) & this._sigma[Convert.ToInt16(str[i])];
				if ((r & this._t) != 0)
				{
					for (j = 0; j < this._patterns.Length; j++)
					{
						int key = (int)(r & check[j]);
						if (key != 0)
						{
							if (!this._founds.ContainsKey(j))
							{
								this._founds.Add(j, new List<int>());

							}
							this._founds[j].Add(i);
						}
					}
                }
            }
        }
    }
}
